home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / uucp-104.lha / uucp-1.04 / log.c < prev    next >
C/C++ Source or Header  |  1993-02-13  |  17KB  |  700 lines

  1. /* log.c
  2.    Routines to add entries to the log files.
  3.  
  4.    Copyright (C) 1991, 1992 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #if USE_RCS_ID
  29. const char log_rcsid[] = "$Id: log.c,v 1.40 1993/01/17 04:18:19 ian Rel $";
  30. #endif
  31.  
  32. #include <errno.h>
  33.  
  34. #if ANSI_C
  35. #include <stdarg.h>
  36. #endif
  37.  
  38. #if HAVE_TIME_H
  39. #include <time.h>
  40. #endif
  41.  
  42. #include "uudefs.h"
  43. #include "uuconf.h"
  44. #include "system.h"
  45.  
  46. /* Local functions.  */
  47.  
  48. static const char *zldate_and_time P((void));
  49.  
  50. /* Log file name.  */
  51. static const char *zLogfile;
  52.  
  53. /* The function to call when a LOG_FATAL error occurs.  */
  54. static void (*pfLfatal) P((void));
  55.  
  56. /* Whether to go to a file.  */
  57. static boolean fLfile;
  58.  
  59. /* ID number.  */
  60. static int iLid;
  61.  
  62. /* The current user name.  */
  63. static char *zLuser;
  64.  
  65. /* The current system name.  */
  66. static char *zLsystem;
  67.  
  68. /* The current device name.  */
  69. char *zLdevice;
  70.  
  71. /* The open log file.  */
  72. static FILE *eLlog;
  73.  
  74. /* Whether we have tried to open the log file.  We need this because
  75.    we don't want to keep trying to open the log file if we failed the
  76.    first time.  It can't be static because under HAVE_HDB_LOGGING we
  77.    may have to write to various different log files.  */
  78. static boolean fLlog_tried;
  79.  
  80. #if DEBUG > 1
  81. /* Debugging file name.  */
  82. static const char *zLdebugfile;
  83.  
  84. /* The open debugging file.  */
  85. static FILE *eLdebug;
  86.  
  87. /* Whether we've tried to open the debugging file.  */
  88. static boolean fLdebug_tried;
  89.  
  90. /* Whether we've written out any debugging information.  */
  91. static boolean fLdebugging;
  92. #endif
  93.  
  94. /* Statistics file name.  */
  95. static const char *zLstatsfile;
  96.  
  97. /* The open statistics file.  */
  98. static FILE *eLstats;
  99.  
  100. /* Whether we've tried to open the statistics file.  */
  101. static boolean fLstats_tried;
  102.  
  103. /* The array of signals.  The elements are only set to TRUE by the
  104.    default signal handler.  They are only set to FALSE if we don't
  105.    care whether we got the signal or not.  */
  106. volatile sig_atomic_t afSignal[INDEXSIG_COUNT];
  107.  
  108. /* The array of signals to log.  The elements are only set to TRUE by
  109.    the default signal handler.  They are set to FALSE when the signal
  110.    is logged in ulog.  This means that if a signal comes in at just
  111.    the right time we won't log it (or, rather, we'll log it once
  112.    instead of twice), but that is not a catatrophe.  */
  113. volatile sig_atomic_t afLog_signal[INDEXSIG_COUNT];
  114.  
  115. /* Flag that indicates SIGHUP is worth logging.  */
  116. boolean fLog_sighup = TRUE;
  117.  
  118. /* Signal names to use when logging signals.  */
  119. static const char * const azSignal_names[INDEXSIG_COUNT] = INDEXSIG_NAMES;
  120.  
  121. /* If not NULL, ulog calls this function before outputting anything.
  122.    This is used to support cu.  */
  123. void (*pfLstart) P((void));
  124.  
  125. /* If not NULL, ulog calls this function after outputting everything.
  126.    This is used to support cu.  */
  127. void (*pfLend) P((void));
  128.  
  129. /* Set the function to call on a LOG_FATAL error.  */
  130.  
  131. void
  132. ulog_fatal_fn (pfn)
  133.      void (*pfn) P((void));
  134. {
  135.   pfLfatal = pfn;
  136. }
  137.  
  138. /* Decide whether to send log message to the file or not.  */
  139.  
  140. void
  141. ulog_to_file (puuconf, ffile)
  142.      pointer puuconf;
  143.      boolean ffile;
  144. {
  145.   int iuuconf;
  146.  
  147.   iuuconf = uuconf_logfile (puuconf, &zLogfile);
  148.   if (iuuconf != UUCONF_SUCCESS)
  149.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  150.  
  151. #if DEBUG > 1
  152.   iuuconf = uuconf_debugfile (puuconf, &zLdebugfile);
  153.   if (iuuconf != UUCONF_SUCCESS)
  154.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  155. #endif
  156.  
  157.   iuuconf = uuconf_statsfile (puuconf, &zLstatsfile);
  158.   if (iuuconf != UUCONF_SUCCESS)
  159.     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
  160.  
  161.   fLfile = ffile;
  162. }
  163.  
  164. /* Set the ID number.  This will be called by the usysdep_initialize
  165.    if there is something sensible to set it to.  */
  166.  
  167. void
  168. ulog_id (i)
  169.      int i;
  170. {
  171.   iLid = i;
  172. }
  173.  
  174. /* Set the user we are making log entries for.  The arguments will be
  175.    copied into memory.  */
  176.  
  177. void
  178. ulog_user (zuser)
  179.      const char *zuser;
  180. {
  181.   ubuffree (zLuser);
  182.   zLuser = zbufcpy (zuser);
  183. }
  184.  
  185. /* Set the system name we are making log entries for.  The name is copied
  186.    into memory.  */
  187.  
  188. void
  189. ulog_system (zsystem)
  190.   const char *zsystem;
  191. {
  192.   if (zsystem == NULL
  193.       || zLsystem == NULL
  194.       || strcmp (zsystem, zLsystem) != 0)
  195.     {
  196.       ubuffree (zLsystem);
  197.       zLsystem = zbufcpy (zsystem);
  198. #if HAVE_HDB_LOGGING      
  199.       /* Under HDB logging we now must write to a different log file.  */
  200.       ulog_close ();
  201. #endif /* HAVE_HDB_LOGGING */
  202.     }
  203. }
  204.  
  205. /* Set the device name.  This is copied into memory.  */
  206.  
  207. void
  208. ulog_device (zdevice)
  209.      const char *zdevice;
  210. {
  211.   ubuffree (zLdevice);
  212.   zLdevice = zbufcpy (zdevice);
  213. }
  214.  
  215. /* Make a log entry.  We make a token concession to non ANSI_C systems,
  216.    but it clearly won't always work.  */
  217.  
  218. #if ! ANSI_C
  219. #undef HAVE_VFPRINTF
  220. #endif
  221.  
  222. /*VARARGS2*/
  223. #if HAVE_VFPRINTF
  224. void
  225. ulog (enum tlog ttype, const char *zmsg, ...)
  226. #else
  227. void
  228. ulog (ttype, zmsg, a, b, c, d, f, g, h, i, j)
  229.      enum tlog ttype;
  230.      const char *zmsg;
  231. #endif
  232. {
  233. #if HAVE_VFPRINTF
  234.   va_list parg;
  235. #endif
  236.   FILE *e, *edebug;
  237.   boolean fstart, fend;
  238.   const char *zhdr, *zstr;
  239.  
  240.   /* Log any received signal.  We do it this way to avoid calling ulog
  241.      from the signal handler.  A few routines call ulog to get this
  242.      message out with zmsg == NULL.  */
  243.   {
  244.     static boolean fdoing_sigs;
  245.  
  246.     if (! fdoing_sigs)
  247.       {
  248.     int isig;
  249.  
  250.     fdoing_sigs = TRUE;
  251.     for (isig = 0; isig < INDEXSIG_COUNT; isig++)
  252.       {
  253.         if (afLog_signal[isig])
  254.           {
  255.         afLog_signal[isig] = FALSE;
  256.  
  257.         /* Apparently SunOS sends SIGINT rather than SIGHUP
  258.            when hanging up, so we don't log either signal if
  259.            fLog_sighup is FALSE.  */
  260.         if ((isig != INDEXSIG_SIGHUP && isig != INDEXSIG_SIGINT)
  261.             || fLog_sighup)
  262.           ulog (LOG_ERROR, "Got %s signal", azSignal_names[isig]);
  263.           }
  264.       }
  265.     fdoing_sigs = FALSE;
  266.       }
  267.   }
  268.  
  269.   if (zmsg == NULL)
  270.     return;
  271.  
  272. #if DEBUG > 1
  273.   /* If we've had a debugging file open in the past, then we want to
  274.      write all log file entries to the debugging file even if it's
  275.      currently closed.  */
  276.   if (fLfile
  277.       && eLdebug == NULL
  278.       && ! fLdebug_tried
  279.       && (fLdebugging || (int) ttype >= (int) LOG_DEBUG))
  280.     {
  281.       fLdebug_tried = TRUE;
  282.       eLdebug = esysdep_fopen (zLdebugfile, FALSE, TRUE, TRUE);
  283.       fLdebugging = TRUE;
  284.     }
  285. #endif /* DEBUG > 1 */
  286.  
  287.   if (! fLfile)
  288.     e = stderr;
  289. #if DEBUG > 1
  290.   else if ((int) ttype >= (int) LOG_DEBUG)
  291.     {
  292.       e = eLdebug;
  293.  
  294.       /* If we can't open the debugging file, don't output any
  295.      debugging messages.  */
  296.       if (e == NULL)
  297.     return;
  298.     }
  299. #endif /* DEBUG > 1 */
  300.   else
  301.     {
  302.       if (eLlog == NULL && ! fLlog_tried)
  303.     {
  304.       fLlog_tried = TRUE;
  305. #if ! HAVE_HDB_LOGGING
  306.       eLlog = esysdep_fopen (zLogfile, TRUE, TRUE, TRUE);
  307. #else /* HAVE_HDB_LOGGING */
  308.       {
  309.         const char *zsys;
  310.         char *zfile;
  311.  
  312.         /* We want to write to .Log/program/system, e.g.      
  313.            .Log/uucico/uunet.  The system name may not be set.  */
  314.         if (zLsystem == NULL)
  315.           zsys = "ANY";
  316.         else
  317.           zsys = zLsystem;
  318.  
  319.         zfile = zbufalc (strlen (zLogfile)
  320.                  + strlen (abProgram)
  321.                  + strlen (zsys)
  322.                  + 1);
  323.         sprintf (zfile, zLogfile, abProgram, zsys);
  324.         eLlog = esysdep_fopen (zfile, TRUE, TRUE, TRUE);
  325.         ubuffree (zfile);
  326.       }
  327. #endif /* HAVE_HDB_LOGGING */
  328.  
  329.       if (eLlog == NULL)
  330.         {
  331.           /* We can't open the log file.  We don't even have a
  332.          safe way to report this problem, since we may not be
  333.          able to write to stderr (it may, for example, be
  334.          attached to the incoming call).  */
  335.           if (pfLfatal != NULL)
  336.         (*pfLfatal) ();
  337.           usysdep_exit (FALSE);
  338.         }
  339.     }
  340.  
  341.       e = eLlog;
  342.  
  343.       /* eLlog might be NULL here because we might try to open the log
  344.      file recursively via esysdep_fopen.  */
  345.       if (e == NULL)
  346.     return;
  347.     }
  348.  
  349.   if (pfLstart != NULL)
  350.     (*pfLstart) ();
  351.  
  352.   edebug = NULL;
  353. #if DEBUG > 1
  354.   if ((int) ttype < (int) LOG_DEBUG)
  355.     edebug = eLdebug;
  356. #endif
  357.  
  358.   fstart = TRUE;
  359.   fend = TRUE;
  360.  
  361.   switch (ttype)
  362.     {
  363.     case LOG_NORMAL:
  364.       zhdr = "";
  365.       break;
  366.     case LOG_ERROR:
  367.       zhdr = "ERROR: ";
  368.       break;
  369.     case LOG_FATAL:
  370.       zhdr = "FATAL: ";
  371.       break;
  372. #if DEBUG > 1
  373.     case LOG_DEBUG:
  374.       zhdr = "DEBUG: ";
  375.       break;
  376.     case LOG_DEBUG_START:
  377.       zhdr = "DEBUG: ";
  378.       fend = FALSE;
  379.       break;
  380.     case LOG_DEBUG_CONTINUE:
  381.       zhdr = NULL;
  382.       fstart = FALSE;
  383.       fend = FALSE;
  384.       break;
  385.     case LOG_DEBUG_END:
  386.       zhdr = NULL;
  387.       fstart = FALSE;
  388.       break;
  389. #endif
  390.     default:
  391.       zhdr = "???: ";
  392.       break;
  393.     }
  394.  
  395.   if (fstart)
  396.     {
  397.       if (! fLfile)
  398.     {
  399.       fprintf (e, "%s: ", abProgram);
  400.       if (edebug != NULL)
  401.         fprintf (edebug, "%s: ", abProgram);
  402.     }
  403.       else
  404.     {
  405. #if HAVE_TAYLOR_LOGGING
  406.       fprintf (e, "%s ", abProgram);
  407.       if (edebug != NULL)
  408.         fprintf (edebug, "%s ", abProgram);
  409. #else /* ! HAVE_TAYLOR_LOGGING */
  410.       fprintf (e, "%s ", zLuser == NULL ? "uucp" : zLuser);
  411.       if (edebug != NULL)
  412.         fprintf (edebug, "%s ", zLuser == NULL ? "uucp" : zLuser);
  413. #endif /* HAVE_TAYLOR_LOGGING */
  414.  
  415.       fprintf (e, "%s ", zLsystem == NULL ? "-" : zLsystem);
  416.       if (edebug != NULL)
  417.         fprintf (edebug, "%s ", zLsystem == NULL ? "-" : zLsystem);
  418.  
  419. #if HAVE_TAYLOR_LOGGING
  420.       fprintf (e, "%s ", zLuser == NULL ? "-" : zLuser);
  421.       if (edebug != NULL)
  422.         fprintf (edebug, "%s ", zLuser == NULL ? "-" : zLuser);
  423. #endif /* HAVE_TAYLOR_LOGGING */
  424.  
  425.       zstr = zldate_and_time ();
  426.       fprintf (e, "(%s", zstr);
  427.       if (edebug != NULL)
  428.         fprintf (edebug, "(%s", zstr); 
  429.  
  430.       if (iLid != 0)
  431.         {
  432. #if ! HAVE_HDB_LOGGING
  433. #if HAVE_TAYLOR_LOGGING
  434.           fprintf (e, " %d", iLid);
  435.           if (edebug != NULL)
  436.         fprintf (edebug, " %d", iLid);
  437. #else /* ! HAVE_TAYLOR_LOGGING */
  438.           fprintf (e, "-%d", iLid);
  439.           if (edebug != NULL)
  440.         fprintf (edebug, "-%d", iLid);
  441. #endif /* ! HAVE_TAYLOR_LOGGING */
  442. #else /* HAVE_HDB_LOGGING */
  443.  
  444.           /* I assume that the second number here is meant to be
  445.          some sort of file sequence number, and that it should
  446.          correspond to the sequence number in the statistics
  447.          file.  I don't have any really convenient way to do
  448.          this, so I won't unless somebody thinks it's very
  449.          important.  */
  450.           fprintf (e, ",%d,%d", iLid, 0);
  451.           if (edebug != NULL)
  452.         fprintf (edebug, ",%d,%d", iLid, 0);
  453. #endif /* HAVE_HDB_LOGGING */
  454.         }
  455.  
  456.       fprintf (e, ") ");
  457.       if (edebug != NULL)
  458.         fprintf (edebug, ") ");
  459.  
  460.       fprintf (e, "%s", zhdr);
  461.       if (edebug != NULL)
  462.         fprintf (edebug, "%s", zhdr);
  463.     }
  464.     }
  465.  
  466. #if HAVE_VFPRINTF
  467.   va_start (parg, zmsg);
  468.   vfprintf (e, zmsg, parg);
  469.   va_end (parg);
  470.   if (edebug != NULL)
  471.     {
  472.       va_start (parg, zmsg);
  473.       vfprintf (edebug, zmsg, parg);
  474.       va_end (parg);
  475.     }
  476. #else /* ! HAVE_VFPRINTF */
  477.   fprintf (e, zmsg, a, b, c, d, f, g, h, i, j);
  478.   if (edebug != NULL)
  479.     fprintf (edebug, zmsg, a, b, c, d, f, g, h, i, j);
  480. #endif /* ! HAVE_VFPRINTF */
  481.  
  482.   if (fend)
  483.     {
  484.       fprintf (e, "\n");
  485.       if (edebug != NULL)
  486.     fprintf (edebug, "\n");
  487.     }
  488.  
  489.   (void) fflush (e);
  490.   if (edebug != NULL)
  491.     (void) fflush (edebug);
  492.  
  493.   if (pfLend != NULL)
  494.     (*pfLend) ();
  495.  
  496.   if (ttype == LOG_FATAL)
  497.     {
  498.       if (pfLfatal != NULL)
  499.     (*pfLfatal) ();
  500.       usysdep_exit (FALSE);
  501.     }
  502.  
  503. #if CLOSE_LOGFILES
  504.   ulog_close ();
  505. #endif
  506. }
  507.  
  508. /* Log a uuconf error.  */
  509.  
  510. void
  511. ulog_uuconf (ttype, puuconf, iuuconf)
  512.      enum tlog ttype;
  513.      pointer puuconf;
  514.      int iuuconf;
  515. {
  516.   char ab[512];
  517.  
  518.   (void) uuconf_error_string (puuconf, iuuconf, ab, sizeof ab);
  519.   ulog (ttype, "%s", ab);
  520. }
  521.  
  522. /* Close the log file.  There's nothing useful we can do with errors,
  523.    so we don't check for them.  */
  524.  
  525. void
  526. ulog_close ()
  527. {
  528.   /* Make sure we logged any signal we received.  */
  529.   ulog (LOG_ERROR, (const char *) NULL);
  530.  
  531.   if (eLlog != NULL)
  532.     {
  533.       (void) fclose (eLlog);
  534.       eLlog = NULL;
  535.       fLlog_tried = FALSE;
  536.     }
  537.  
  538. #if DEBUG > 1
  539.   if (eLdebug != NULL)
  540.     {
  541.       (void) fclose (eLdebug);
  542.       eLdebug = NULL;
  543.       fLdebug_tried = FALSE;
  544.     }
  545. #endif
  546. }
  547.  
  548. /* Add an entry to the statistics file.  We may eventually want to put
  549.    failed file transfers in here, but we currently do not.  */
  550.  
  551. /*ARGSUSED*/
  552. void
  553. ustats (fsucceeded, zuser, zsystem, fsent, cbytes, csecs, cmicros, fmaster)
  554.      boolean fsucceeded;
  555.      const char *zuser;
  556.      const char *zsystem;
  557.      boolean fsent;
  558.      long cbytes;
  559.      long csecs;
  560.      long cmicros;
  561.      boolean fmaster;
  562. {
  563.   long cbps;
  564.  
  565.   /* The seconds and microseconds are now counted independently, so
  566.      they may be out of synch.  */
  567.   if (cmicros < 0)
  568.     {
  569.       csecs -= ((- cmicros) / 1000000L) + 1;
  570.       cmicros = 1000000L - ((- cmicros) % 1000000L);
  571.     }
  572.   if (cmicros >= 1000000L)
  573.     {
  574.       csecs += cmicros / 10000000L;
  575.       cmicros = cmicros % 1000000L;
  576.     }      
  577.  
  578.   /* On a system which can determine microseconds we might very well
  579.      have both csecs == 0 and cmicros == 0.  */
  580.   if (csecs == 0 && cmicros < 1000)
  581.     cbps = 0;
  582.   else
  583.     {
  584.       long cmillis;
  585.  
  586.       /* This computation will not overflow provided csecs < 2147483
  587.      and cbytes and cbps both fit in a long.  */
  588.       cmillis = csecs * 1000 + cmicros / 1000;
  589.       cbps = ((cbytes / cmillis) * 1000
  590.           + ((cbytes % cmillis) * 1000) / cmillis);
  591.     }
  592.  
  593.   if (eLstats == NULL)
  594.     {
  595.       if (fLstats_tried)
  596.     return;
  597.       fLstats_tried = TRUE;
  598.       eLstats = esysdep_fopen (zLstatsfile, TRUE, TRUE, TRUE);
  599.       if (eLstats == NULL)
  600.     return;
  601.     }
  602.  
  603. #if HAVE_TAYLOR_LOGGING
  604.   fprintf (eLstats,
  605.        "%s %s (%s) %s%s %ld bytes in %ld.%03ld seconds (%ld bytes/sec)\n",
  606.        zuser, zsystem, zldate_and_time (),
  607.        fsucceeded ? "" : "failed after ",
  608.        fsent ? "sent" : "received",
  609.        cbytes, csecs, cmicros / 1000, cbps);
  610. #endif /* HAVE_TAYLOR_LOGGING */
  611. #if HAVE_V2_LOGGING
  612.   fprintf (eLstats,
  613.        "%s %s (%s) (%ld) %s %s %ld bytes %ld seconds\n",
  614.        zuser, zsystem, zldate_and_time (),
  615.        (long) time ((time_t *) NULL),
  616.        fsent ? "sent" : "received",
  617.        fsucceeded ? "data" : "failed after",
  618.        cbytes, csecs + cmicros / 500000);
  619. #endif /* HAVE_V2_LOGGING */
  620. #if HAVE_HDB_LOGGING
  621.   {
  622.     static int iseq;
  623.  
  624.     /* I don't know what the 'C' means.  The sequence number should
  625.        probably correspond to the sequence number in the log file, but
  626.        that is currently always 0; using this fake sequence number
  627.        will still at least reveal which transfers are from different
  628.        calls.  We don't report a failed data transfer with this
  629.        format.  */
  630.     if (! fsucceeded)
  631.       return;
  632.     ++iseq;
  633.     fprintf (eLstats,
  634.          "%s!%s %c (%s) (C,%d,%d) [%s] %s %ld / %ld.%03ld secs, %ld %s\n",
  635.          zsystem, zuser, fmaster ? 'M' : 'S', zldate_and_time (),
  636.          iLid, iseq, zLdevice == NULL ? "unknown" : zLdevice,
  637.          fsent ? "->" : "<-",
  638.          cbytes, csecs, cmicros / 1000, cbps,
  639.          "bytes/sec");
  640.   }
  641. #endif /* HAVE_HDB_LOGGING */
  642.  
  643.   (void) fflush (eLstats);
  644.  
  645. #if CLOSE_LOGFILES
  646.   ustats_close ();
  647. #endif
  648. }
  649.  
  650. /* Close the statistics file.  */
  651.  
  652. void
  653. ustats_close ()
  654. {
  655.   if (eLstats != NULL)
  656.     {
  657.       if (fclose (eLstats) != 0)
  658.     ulog (LOG_ERROR, "fclose: %s", strerror (errno));
  659.       eLstats = NULL;
  660.       fLstats_tried = FALSE;
  661.     }
  662. }
  663.  
  664. /* Return the date and time in a form used for a log entry.  */
  665.  
  666. static const char *
  667. zldate_and_time ()
  668. {
  669.   long isecs, imicros;
  670.   struct tm s;
  671. #if HAVE_TAYLOR_LOGGING
  672.   static char ab[sizeof "1991-12-31 12:00:00.00"];
  673. #endif
  674. #if HAVE_V2_LOGGING
  675.   static char ab[sizeof "12/31-12:00"];
  676. #endif
  677. #if HAVE_HDB_LOGGING
  678.   static char ab[sizeof "12/31-12:00:00"];
  679. #endif
  680.  
  681.   isecs = ixsysdep_time (&imicros);
  682.   usysdep_localtime (isecs, &s);
  683.  
  684. #if HAVE_TAYLOR_LOGGING
  685.   sprintf (ab, "%04d-%02d-%02d %02d:%02d:%02d.%02d",
  686.        s.tm_year + 1900, s.tm_mon + 1, s.tm_mday, s.tm_hour,
  687.        s.tm_min, s.tm_sec, (int) (imicros / 10000));
  688. #endif
  689. #if HAVE_V2_LOGGING
  690.   sprintf (ab, "%d/%d-%02d:%02d", s.tm_mon + 1, s.tm_mday,
  691.        s.tm_hour, s.tm_min);
  692. #endif
  693. #if HAVE_HDB_LOGGING
  694.   sprintf (ab, "%d/%d-%02d:%02d:%02d", s.tm_mon + 1, s.tm_mday,
  695.        s.tm_hour, s.tm_min, s.tm_sec);
  696. #endif
  697.  
  698.   return ab;
  699. }
  700.